package gulimall.consumer;

import com.rabbitmq.client.Channel;
import gulimall.entity.OrderItem;
import gulimall.entity.OrderReturnReason;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author HLF
 * @date 2022/8/20 17:48
 */
@Slf4j
@Component
@RabbitListener(queues = {"test-AmqpAdmin-queue"})
public class MyConsumer {


    /**
     * 参数可以写以下类型
     * 1、Message message：原生消息详细信息。头+体
     * 2、T<发送的消息的类型> OrderReturnReason content；
     * 3、Channel channel：当前传输数据的通道
     * <p>
     * Queue：可以很多人都来监听。只要收到消息，队列删除消息，而且只能有一个收到此消息
     * 场景：
     * 1）、订单服务启动多个；同一个消息，只能有一个客户端收到
     * 2)、 只有一个消息完全处理完，方法运行结束，我们就可以接收到下一个消息
     */
    @RabbitHandler
    public void receiveMsg(Message message, OrderReturnReason content, Channel channel) throws IOException {
        if (content.getId() == 1) {
            /**
             * 参数：
             * 1.消息的标记
             * 2.是否批量应答，为真，以确认所提供的传递标签之前的所有消息；false仅确认提供的交付标签对应的消息。
             * 3.是否重新入队，false表示直接丢弃/死信，true表示重新加入队列，等待消费者进行消费
             *   如果拒绝的消息应重新排队，而不是丢弃/死信，则为真
             */
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            log.info("消息拒绝应答，消息的id：{}", message.getMessageProperties().getMessageId());
        } else {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);

            log.info("消息成功应答...");

            System.out.println("消息内容：" + content);

            System.out.println("消息详细信息(头+体)：" + message);

            MessageProperties messageProperties = message.getMessageProperties();
            System.out.println("deliverTag：" + messageProperties.getDeliveryTag());
        }
    }


    /**
     * 场景：当生产者发送消息的类型不固定时，接收的消息类型也不固定，可以指定不同的@RabbitHandler处理不同类型的消息
     * 使用RabbitHandler接收不同类型的消息
     *
     * @param message
     * @param orderItem
     * @param channel
     */
    @RabbitHandler
    public void receiveMsg(Message message, OrderItem orderItem, Channel channel) {
        // 消费OrderItem类型的消息 ...
    }
}
